import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { Transfer, Table, Spin, Input } from 'antd';
import { axconst } from '@/shared/axconst';
import { TransferProps } from 'antd/lib/transfer';
import difference from 'lodash/difference';
import { AxTableTransferProps } from './data';
import { AxPagination } from '@/components/AxList/AxStandardTable/components/AxPagination';
import styles from './style.less';

const { Search } = Input;

const AxTableTransfer = (props: AxTableTransferProps & Omit<TransferProps, 'listStyle' | 'dataSource' | 'showSearch'>, ref: any) => {
    const {
        data,
        target,
        handleReadData,
        dataSearchField = 'name',
        targetSearchField = 'name',
        searchPlaceholder = '请输入搜索内容',
        leftColumns,
        rightColumns,
        scrollY,
        loading = false,
        ...rest
    } = props;
    const [dataSource, setDataSource] = useState<any[]>([]);
    const [targetKeys, setTargetKeys] = useState<any[]>([]);
    const [targetFilter, setTargetFilter] = useState<any>();
    let scroll = {};
    if (scrollY) scroll = { y: scrollY };

    useImperativeHandle(ref, () => ({
        targetKeys,
    }));

    useEffect(() => {
        let source: any[] = [];
        let dataX: any[] = [];
        let targetX: any[] = [];
        /** 添加key属性 */
        if (data && data.list) {
            source = [...data.list.map((i: any) => ({
                ...i,
                key: i.id,
            }))];
            dataX = [...data.list.map((i: any) => ({
                ...i,
                key: i.id,
            }))];
        }
        if (target && target.list) {
            targetX = [...target.list.map((i: any) => ({
                ...i,
                key: i.id,
            }))];
        }
        /** 将target中的插入到data中 */
        if (dataX.length > 0) {
            targetX.forEach((i: any) => {
                if (!dataX.find((j: any) => i.key === j.key)) {
                    source.push(i);
                }
            });
        }
        else {
            source.push(...targetX);
        }
        setDataSource(source);
    }, [data, target]);

    useEffect(() => {
        if (target && target.list) {
            setTargetKeys(target.list.map((i: any) => i.id));
        }
    }, [target]);

    const handleChange = (keys: any) => {
        setTargetKeys(keys);
    };

    const handleSearch = (direction: 'left' | 'right', value: string) => {
        const v = value.trim();
        if (direction === 'left' && handleReadData) {
            return handleReadData({
                [dataSearchField]: v,
            });
        }
        if (direction === 'right') {
            setTargetFilter(v);
        }
    };

    /** Table分页、排序、筛选事件的响应函数 */
    const handleTableChange = (pagination: any, filtersArg: any, sorter: any) => {
        const page = axconst.page.getParams(pagination);
        const payload = {
            ...page,
        };

        if (handleReadData) return handleReadData({
            ...payload,
        });
    };

    return (
        <>
            <Transfer
                showSelectAll={false}
                targetKeys={targetKeys}
                dataSource={dataSource}
                onChange={handleChange}
                {...rest}
                showSearch={false}
            >
                {({
                    direction,
                    filteredItems,
                    onItemSelectAll,
                    onItemSelect,
                    selectedKeys: listSelectedKeys,
                    disabled: listDisabled,
                }) => {
                    const columns = direction === 'left' ? leftColumns : rightColumns;
                    const filteredItemsX = direction === 'left' ? filteredItems : filteredItems.filter((i: any) => {
                        if (targetFilter && i[targetSearchField]) {
                            return i[targetSearchField].indexOf(targetFilter) > -1;
                        }
                        return true;
                    });

                    const rowSelection = {
                        getCheckboxProps: (item: any) => ({ disabled: listDisabled || item.disabled }),
                        onSelectAll(selected: any, selectedRows: any) {
                            const treeSelectedKeys = selectedRows
                                .filter((item: any) => !item.disabled)
                                .map(({ key }: any) => key);
                            const diffKeys = selected
                                ? difference(treeSelectedKeys, listSelectedKeys)
                                : difference(listSelectedKeys, treeSelectedKeys);
                            onItemSelectAll(diffKeys, selected);
                        },
                        onSelect({ key }: any, selected: any) {
                            onItemSelect(key, selected);
                        },
                        selectedRowKeys: listSelectedKeys,
                    };

                    return (
                        <>
                            <Search
                                placeholder={searchPlaceholder}
                                onSearch={val => handleSearch(direction, val)}
                                style={{ marginBottom: 2 }}
                                allowClear
                            />
                            <Table
                                rowSelection={rowSelection}
                                columns={columns}
                                dataSource={filteredItemsX}
                                size="small"
                                scroll={scroll}
                                style={{ pointerEvents: listDisabled ? 'none' : 'auto' }}
                                pagination={false}
                                onRow={({ key, disabled: itemDisabled }) => ({
                                    onClick: () => {
                                        if (itemDisabled || listDisabled) return;
                                        onItemSelect(key, !listSelectedKeys.includes(key));
                                    },
                                })}
                            />
                            {direction === 'left' && filteredItems.length > 1 && <AxPagination
                                showPagination='mini'
                                pagination={data && data.pagination}
                                onChange={handleTableChange}
                            />}
                        </>
                    );
                }}
            </Transfer>
            {loading && (
                <div className={styles.axLoadingContainer}>
                    <Spin />
                </div>
            )}
        </>
    );
}

export default forwardRef(AxTableTransfer);
